/**
 * 
 */
package fr.univnantes.lina.ftbcleaner;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import fr.univnantes.lina.ftbcleaner.MultiWordDesambiguationCase;
import fr.univnantes.lina.ftbcleaner.WordLemma;


/**
 * @author hernandez
 *
	<w cat="N" ee="N-C-ms" ei="NCms" lemma="premier ministre" mph="ms" subcat="C">
    	<w catint="A">premier</w>
    	<w catint="N">ministre</w>
	</w>

 */
class WordLemma {
	/*
	 * 
	 */
	private String lemma = ""; 							// MW feature, unique; plays the role of key	 
	private List<String> catArrayList = null;			// MW features List de String correspondant à un cat possible 
	private List<String> subcatArrayList = null;		// MW features
	//private ArrayList<String> lemmaArrayList = null;	// MW features
	private List<String> mphArrayList = null;			// MW features
	//private ArrayList<String> eeArrayList = null;
	//private ArrayList<String> eiArrayList = null;
	
	private Map<String,Integer> wordsMap = null; //	// MW features : compte les occurrences des formes de surface de chaque lemme
	private int size = 0; 								// number Of words Part Of the multi Words (maximal size, various forms may have the same lemma, we assume the lemma size is the maximal) 
	// TODO catintsArrayList check if it embeds amalgame
	private int occurrence = 0; // 
	
	/*
	 * 
	 */
	private List<String> catintsArrayList = null; // 	// W partOf MW features : Chaque String correspond à une séquence des catints couverte, 
	// TODO catintsArrayList check if it embeds amalgame
	
	/*
	 * 
	 */
	private Boolean isCatAmbiguous = false;
	private Boolean isSubcatAmbiguous = false;
	//private int hasEmptyWordChildElement = 0; // number of occ with words without contents : assumed be part of an amalgame 
	private int hasAtLeastOneNullCatintValue = 0;  // number of occ with at least one of its word with a catint attribute value empty
	//private int numberOfPartOfWordsNotPartOfAmalgame = 0; // number 
	/*
	 * 
	 */
	private int desambiguisationCase = MultiWordDesambiguationCase.UNDEFINED;
	private Boolean canBeDesambiguated = false; // number
	//private Map<String,Integer> featuresFromSWSeqMap= null;

	private String uniqCommonCatintsSequence; //computed given all the occurrences of the mw lemma 
	private String mostFBSalientCatintsSequence;
	private String mostFrequentCoveringCatintsSequence;
	
	/*private Map<String,String> mostProbableCatintSequenceFromSW ; // determined by searching SW seq corresponding to a MW form
	private Map<String,String> mostProbableSubcatSequenceFromSW ; // determined by searching SW seq corresponding to a MW form
	private Map<String,String> mostProbableLemmaSequenceFromSW ; // determined by searching SW seq corresponding to a MW form
	private Map<String,String> mostProbableMphSequenceFromSW ; // determined by searching SW seq corresponding to a MW form
	*/
	// TODO catintsArrayList check if it embeds amalgame
	
	/**
	 * @return the uniqCommonCatintsSequence
	 */
	protected String getUniqCommonCatintsSequence() {
		return uniqCommonCatintsSequence;
	}

	/**
	 * @param uniqCommonCatintsSequence the uniqCommonCatintsSequence to set
	 */
	protected void setUniqCommonCatintsSequence(String uniqCommonCatintsSequence) {
		this.uniqCommonCatintsSequence = uniqCommonCatintsSequence;
	}

	/**
	 * @return the mostFBSalientCatintsSequence
	 */
	protected String getMostFBSalientCatintsSequence() {
		return mostFBSalientCatintsSequence;
	}

	/**
	 * @param mostFBSalientCatintsSequence the mostFBSalientCatintsSequence to set
	 */
	protected void setMostFBSalientCatintsSequence(
			String mostFBSalientCatintsSequence) {
		this.mostFBSalientCatintsSequence = mostFBSalientCatintsSequence;
	}

	/**
	 * @return the mostFrequentCoveringCatintsSequence
	 */
	protected String getMostFrequentCoveringCatintsSequence() {
		return mostFrequentCoveringCatintsSequence;
	}

	/**
	 * @param mostFrequentCoveringCatintsSequence the mostFrequentCoveringCatintsSequence to set
	 */
	protected void setMostFrequentCoveringCatintsSequence(
			String mostFrequentCoveringCatintsSequence) {
		this.mostFrequentCoveringCatintsSequence = mostFrequentCoveringCatintsSequence;
	}

	
	/**
	 * @return the size
	 */
	protected int getSize() {
		return size;
	}
	
	/**
	 * @return the canBeDesambiguated
	 */
	protected Boolean getCanBeDesambiguated() {
		return canBeDesambiguated;
	}

	/**
	 * @param canBeDesambiguated the canBeDesambiguated to set
	 */
	protected void setCanBeDesambiguated(Boolean canBeDesambiguated) {
		this.canBeDesambiguated = canBeDesambiguated;
	}

	/**
	 * @return the desambiguisationCase
	 */
	protected int getDesambiguisationCase() {
		return desambiguisationCase;
	}

	/**
	 * @param desambiguisationCase the desambiguisationCase to set
	 */
	protected void setDesambiguisationCase(int desambiguisationCase) {
		this.desambiguisationCase = desambiguisationCase;
	}

	/**
	 * @return the numberOfPartOfWordsNotPartOfAmalgame
	 */
	//protected int getNumberOfPartOfWordsNotPartOfAmalgame() {
	//	return numberOfPartOfWordsNotPartOfAmalgame;
	//}

	/**
	 * @return the catArrayList
	 */
	protected List<String> getCatArrayList() {
		return catArrayList;
	}

	/**
	 * @return the subcatArrayList
	 */
	protected List<String> getSubcatArrayList() {
		return subcatArrayList;
	}

	/**
	 * @return the mphArrayList
	 */
	protected List<String> getMphArrayList() {
		return mphArrayList;
	}

	/**
	 * @return the catintsArrayList
	 */
	protected List<String> getCatintsArrayList() {
		return catintsArrayList;
	}

	/**
	 * @return the wordsMap
	 */
	protected Map<String,Integer> getWordsMap() {
		return wordsMap;
	}

	/**
	 * @return the various surface forms of lemma
	 */
	protected Set<String> getWordForms() {
		return wordsMap.keySet();
	}
	
	/**
	 * @return the firstWordMap
	 */
	//public Map<String,Set<String>> getFirstWordMap() {
	//	return firstWordMap;
	//}
	
	/**
	 * @deprecated
	 * @return the size
	 */
	//protected int getSize() {
	//	return size;
	//}

	/**
	 * @return the occurrence
	 */
	protected int getOccurrence() {
		return occurrence;
	}

	/**
	 * @return the isCatAmbiguous
	 */
	protected Boolean getIsCatAmbiguous() {
		return isCatAmbiguous;
	}

	/**
	 * @return the isSubcatAmbiguous
	 */
	protected Boolean getIsSubcatAmbiguous() {
		return isSubcatAmbiguous;
	}

	/**
	 * @return the lemma
	 */
	protected String getLemma() {
		return this.lemma;
	}

	
	/**
	 * @return the catint sequence
	 */
	//protected Map<String,String> getMostProbableCatintSequence() {
	//	return this.mostProbableCatintSequenceFromSW;
	//}
	
	/**
	 * Set a catint sequence
	 */
	//protected void addMostProbableCatintSequence(String wordForm, String value) {
	//	this.mostProbableCatintSequenceFromSW.put(wordForm, value);
	//}

	/**
	 * @return the subcat sequence
	 */
	//protected Map<String,String> getMostProbableSubcatSequence() {
	//	return this.mostProbableSubcatSequenceFromSW;
	//}
	
	/**
	 * Set a subcat sequence
	 */
	//protected void addMostProbableSubcatSequence(String wordForm, String value) {
	//		this.mostProbableSubcatSequenceFromSW.put(wordForm, value);
	//}
	
	/**
	 * @return the lemma sequence
	 */
	//	protected Map<String,String> getMostProbableLemmaSequence() {
	//		return this.mostProbableLemmaSequenceFromSW;
	//	}
	
	/**
	 * Set a lemma sequence
	 */
	//	protected void addMostProbableLemmaSequence(String wordForm, String value) {
	//		this.mostProbableLemmaSequenceFromSW.put(wordForm, value);
	//	}

	/**
	 * @return the mph sequence
	 */
	//	protected Map<String,String> getMostProbableMphSequence() {
	//		return this.mostProbableMphSequenceFromSW;
	//	}
	
	/**
	 * Set a mph sequence
	 */
	//protected void addMostProbableMphSequence(String wordForm, String value) {
	//		this.mostProbableMphSequenceFromSW.put(wordForm, value);
	//	}

	
	/**
	 * @return the hasPartOfAmalgame
	 */
	//protected int getHasPartOfAmalgame() {
	//	return hasEmptyWordChildElement;
	//}

	/**
	 * @return the hasEmptyCatints
	 */
	protected int getNumberOfNullCatintValue() {
		return hasAtLeastOneNullCatintValue;
	}
	
	/**
	 * 
	 * @param lemma
	 * @param cat
	 * @param subcat
	 * @param mph
	 * @param catints
	 * @param words
	 * @param hasPartOfAmalgame
	 * @param hasEmptyCatints
	 * @param numberOfPartOfWordsNotPartOfAmalgame
	 * @param numberOfPartOfWords TODO
	 */
	public WordLemma (String lemma, String cat, String subcat, String mph, 
			String catints, String words,  
			Boolean hasEmptyCatints, int numberOfPartOfWords) {
		this.lemma = lemma;
		this.catArrayList = new ArrayList<String>();
		this.subcatArrayList = new ArrayList<String>();
		this.mphArrayList = new ArrayList<String>();
		this.catintsArrayList  = new ArrayList<String>();
		this.wordsMap = new HashMap<String,Integer>();
		//	this.mostProbableCatintSequenceFromSW = new HashMap<String,String>();
		//		this.mostProbableSubcatSequenceFromSW = new HashMap<String,String>();
		//	this.mostProbableLemmaSequenceFromSW = new HashMap<String,String>();
		//	this.mostProbableMphSequenceFromSW = new HashMap<String,String>();
	//	this.featuresFromSWSeqMap = new HashMap<String, Integer>(); // Coming from sequence of simple words matched, word catint, subcat lemma mph separated by ' ' and words by '\'
		updateMultiWordExpression(cat, subcat, mph, catints, words, 
				hasEmptyCatints,  numberOfPartOfWords);
	}

	/**
	 * 
	 * @param cat
	 * @param subcat
	 * @param mph
	 * @param catints
	 * @param words
	 * @param hasPartOfAmalgame
	 * @param hasEmptyCatints
	 * @param numberOfPartOfWordsNotPartOfAmalgame
	 * @param numberOfPartOfWords TODO
	 * @return
	 */
	public WordLemma updateMultiWordExpression (String cat, String subcat, String mph, String catints, 
			String words, Boolean hasEmptyCatints, int numberOfPartOfWords) {
		this.occurrence += 1;
		if (!(cat.trim()).equalsIgnoreCase("")) this.catArrayList.add(cat);
		if (!(subcat.trim()).equalsIgnoreCase("")) this.subcatArrayList.add(subcat);
		if (!(mph.trim()).equalsIgnoreCase("")) this.mphArrayList.add(mph);
		if (!(catints.trim()).equalsIgnoreCase("")) this.catintsArrayList.add(catints);
		//String localWords = 
		if (!(words.trim()).equalsIgnoreCase("")) {
			if (wordsMap.containsKey(words.trim())) 
				wordsMap.put(words.trim(), wordsMap.get(words.trim())+1);
			else
				wordsMap.put(words.trim(), new Integer(1));
			//String localWords[] = words.trim().split(" ");
			//if (firstWordMap.containsKey(localWords[0])) {
			//	firstWordMap.get(localWords[0]).add(words.trim());
			//	//this.firstWordMap.put(
			//	//		localWords[0], firstWordMap.get(localWords[0]) // (Set<String>) ((firstWordMap.get(localWords[0])).add(words.trim()))
			//	//		);
			//}
			//else {
			//	Set<String> wordsSet = new HashSet<String>();
			//	wordsSet.add(words.trim());
			//	firstWordMap.put(localWords[0], wordsSet);
			//}
		}
		//if (numberOfPartOfWordsNotPartOfAmalgame > this.numberOfPartOfWordsNotPartOfAmalgame) 
		//	this.numberOfPartOfWordsNotPartOfAmalgame = numberOfPartOfWordsNotPartOfAmalgame;
		// TODO some mw can be and some others not... !!!
		//if (hasPartOfAmalgame != false) this.hasEmptyWordChildElement++;
		if (hasEmptyCatints != false) this.hasAtLeastOneNullCatintValue++;
		if (this.size < numberOfPartOfWords) this.size = numberOfPartOfWords;
		//			this.display();
		return this;
	}

	/**
	 * 
	 */
	public void display () {
		System.out.println(lemma);
		Iterator<String> myIterator = catArrayList.iterator();
		System.out.print("  cat ");
		while  (myIterator.hasNext()) {
			String currentString = (String) myIterator.next();
			System.out.print("  "+currentString);
		}
		System.out.println();

		System.out.print("  subcat ");
		myIterator = subcatArrayList.iterator();
		while  (myIterator.hasNext()) {
			String currentString = (String) myIterator.next();
			System.out.print("  "+currentString);
		}
		System.out.println();

		System.out.print("  catints ");
		myIterator = catintsArrayList.iterator();
		while  (myIterator.hasNext()) {
			String currentString = (String) myIterator.next();
			System.out.print("  "+currentString);
		}
		System.out.println();

		System.out.println ("  words "+wordsMap.keySet().toString());
		
//		System.out.print("  feats (from SW seq) "+featuresFromSWSeqSet.toString());
//		if (featuresFromSWSeqSet.size() >1) System.out.println(" !!!");
		//System.out.print("  feats (from SW seq) "+featuresFromSWSeqMap.keySet().toString());
		//if (featuresFromSWSeqMap.keySet().size() >1) System.out.println(" !!!");

		//else System.out.println();
			
		//System.out.println("  #partOfWordsNotAmalgame "+numberOfPartOfWordsNotPartOfAmalgame);

		//if (hasEmptyWordChildElement > 0) System.out.println("  has "+hasEmptyWordChildElement+" PartOfAmalgame");
		if (hasAtLeastOneNullCatintValue > 0) System.out.println("  has "+hasAtLeastOneNullCatintValue+" EmptyCatints");
		//if (!mostProbableCatintSequenceFromSW.keySet().isEmpty()) System.out.println(" cats "+mostProbableCatintSequenceFromSW.values()); 
		System.out.println();
	}

}
